<template>
  <el-dialog
    :model-value="containersDialogVisible"
    title="终端"
    width="70%"
    @close="handleClose"
  >
      <div style="display: flex;justify-content: center">
         <el-tag size="large" type="primary" style="margin-right: 10px;">Pod名称：{{props.resource_name}}</el-tag>
         <el-select filterable v-model="containers" class="m-2" @click="getContainers"  placeholder="请选择容器" style="width: 250px;">
            <el-option v-for="(c,index) in containers_list" :key="index" :label="c" :value="c" >
            </el-option>
          </el-select>
      </div>
     <div ref="xterm" class="terminal" style="height: 500px;margin-top: 20px"/>

    <template #footer>
      <span class="dialog-footer">
        <el-button @click="handleClose">取消</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, watch, onMounted, defineProps, defineEmits } from 'vue';
import requestUtil from '@/util/request';
import { ElMessage } from 'element-plus';
//终端
import 'xterm/css/xterm.css'
import { Terminal } from 'xterm'
import { FitAddon } from 'xterm-addon-fit'


// 定义Props
const props = defineProps({
  resource_name: {
    type: String,
    required: true,
    default: '',
  },
  resource_namespace: {
    type: String,
    required: true,
    default: '',
  },
  resource_containers: {
    type: String,
    required: true,
    default: '',
  },
  containersDialogVisible: {
    type: Boolean,
    required: true,
    default: false,
  },
});

const containers = ref()
const containers_list = ref([])
const getContainers = () => {
  containers_list.value = []
  const containers_obj = props.resource_containers
  for(let c in containers_obj) {
      containers_list.value.push(containers_obj[c]['c_name'])
  }
}


const xterm = ref('')
const term = ref('')
const ws = ref('')

// 定义Emits
const emits = defineEmits(['update:modelValue']);

// 初始化Terminal
const init = () => {
    term.value = new Terminal({
      fontSize: 18,
      convertEol: true, // 启用时，光标将设置为下一行的开头
      rendererType: 'canvas', // 渲染类型
      cursorBlink: true, // 光标闪烁
      cursorStyle: 'bar', // 光标样式 underline
      theme: {
        background: '#060101', // 背景色
        cursor: 'help' // 设置光标
       }
    })
};
// 初始化Websocket
const initSocket = () =>{
    const fitPlugin = new FitAddon()
    fitPlugin.activate(term.value)

    // 建立ws连接
    ws.value = new WebSocket(`ws://${process.env.VUE_APP_API_HOST}:${process.env.VUE_APP_API_PORT}/workload/container_terminal/${props.resource_namespace}/${props.resource_name}/${containers.value}/`)

    // 建立ws连接成功后回调
    ws.value.onopen = () => {
      // 将term挂载到标签上
      term.value.open(xterm.value)
      term.value.focus()
      fitPlugin.fit()
    }

    // 获取后端传回的数据
    ws.value.onmessage = (res) => {
      term.value.write(res.data)
    }

    // 用户输入发送到后端
    term.value.onData(data => ws.value.send(data))

    // ws关闭连接
    ws.value.onclose = (e) => {
        console.log('Websocket关闭：' + e)
    }
};

//清理websocket和终端资源
const cleanupSocket = () =>{
    if (ws.value){
      ws.value.close();
    }
    if (term.value){
      term.value.dispose();
    }
};

// 监听打开窗口
watch(() => props.containersDialogVisible, (newValue) => {
  if (newValue) {
    containers.value = props.resource_containers[0]['c_name']
    init()
    initSocket()
  }
});

// 关闭对话框
const handleClose = () => {
  cleanupSocket();
  emits('update:modelValue', false);
};


</script>

<style scoped>

</style>